﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.ServiceModel.Channels;
using System.Threading;
using Smith.AMC;
using Smith.AMC.Configuration;
using Smith.AMC.Network;

namespace SoakTest
{
    class Program
    {
        static void Main(string[] args)
        {

            //List<KeyValuePair<IPAddress, int>> servers = new List<KeyValuePair<IPAddress, int>>();
            //servers.Add(new KeyValuePair<IPAddress, int>(IPAddress.Parse("127.0.0.1"), 11211));
            ////servers.Add(new KeyValuePair<IPAddress, int>(IPAddress.Parse("127.0.0.1"), 11222));
            //ServerNodeMonitorConfiguration config = new ServerNodeMonitorConfiguration();
            //ServerPool pool = new ServerPool(servers, SocketType.Stream, ProtocolType.Tcp, 30, config);
            //MemcachedClient client = new MemcachedClient(new SocketWorker(pool, TimeSpan.FromSeconds(20)));
            MemcachedClient client = new MemcachedClient();
            List<Thread> threads = new List<Thread>();
            ManualResetEvent evt = new ManualResetEvent(false);
            long exceptions = 0;
            long tries = 0;
            long succeded = 0;
            long failed = 0;
            object fileSystemLock = new object();
            int numberOfThreads = 2;
            Thread t = new Thread(()=>{
                Console.WriteLine("Wating to stop");
                Thread.Sleep(60 * 1000);

                evt.Set();
            });
            t.Start();

            for (int x = 0; x < numberOfThreads; x++)
            {
                Thread t1 = new Thread(() =>
                {
                    do
                    {
                        ICacheItem<string> item = new CacheItem<string>
                                                      {
                                                          CacheKey = Guid.NewGuid().ToString(),
                                                          LifeTime = TimeSpan.FromSeconds(0),
                                                          Value = "This is the value"
                                                      };
                        IAsyncResult asyncResult = client.BeginAdd(item, null, null);
                        bool success = client.EndAdd<string>(asyncResult);

                        if (success)
                        {
                            Interlocked.Increment(ref succeded);
                        }
                        else
                        {
                            Interlocked.Increment(ref failed);
                        }

                    } while (!evt.WaitOne(0, false));
                });
                t1.Start();
            }

            //for (int x = 0; x < 30; x++)
            //{
            //    Thread t = new Thread(obj =>
            //    {
            //        do
            //        {
            //            ManualResetEvent evt2 = new ManualResetEvent(false);
            //            ICacheItem<string> item = new CacheItem<string>
            //            {
            //                CacheKey = Guid.NewGuid().ToString(),
            //                LifeTime = TimeSpan.FromSeconds(0),
            //                Value = "This is the value"
            //            };

            //            Interlocked.Increment(ref tries);

            //            client.BeginAdd(
            //                item,
            //                ar =>
            //                {
            //                    ManualResetEvent evtInner = (ManualResetEvent)ar.AsyncState;
            //                    try
            //                    {
            //                        bool success = client.EndAdd<string>(ar);

            //                        if (success)
            //                        {
            //                            Interlocked.Increment(ref succeded);
            //                        }
            //                        else
            //                        {
            //                            Interlocked.Increment(ref failed);
            //                        }
            //                    }
            //                    catch (Exception e)
            //                    {
            //                        Interlocked.Increment(ref exceptions);
            //                        lock (fileSystemLock)
            //                        {
            //                            using (StreamWriter sw = File.AppendText("D:\\error.log"))
            //                            {
            //                                sw.WriteLine(e.ToString());
            //                            }
            //                        }
            //                    }
            //                    finally
            //                    {
            //                        evtInner.Set();
            //                    }
            //                },
            //                evt2);
            //            evt2.WaitOne();
            //        } while (!evt.WaitOne(1, false));

            //    });
            //    threads.Add(t);
            //}

            //threads.ForEach(t => t.Start());

            // Sleep for 7 hours hour, to make client run for 8 hours
            //Thread.Sleep(1000 * 10);
            //Thread.Sleep(1000 * 60 * 60 * 8);
            //Thread.Sleep(1000 * 60);

            //evt.Set();
            // Sleep to make threads capable of finishing
            //Thread.Sleep(5000);
            //threads.ForEach(t => t.Join());
            evt.WaitOne();
            Thread.Sleep(100);
            Console.WriteLine("Tries:{0}", tries);
            Console.WriteLine("Succeded:{0}", succeded);
            Console.WriteLine("Failed:{0}", failed);
            Console.WriteLine("Exceptions:{0}", exceptions);
        }
    }
}
